package com.filldream.fastboot.common.util;

import com.filldream.fastboot.common.exception.GlobalException;
import com.filldream.fastboot.common.entity.ErrorCode;
import com.filldream.fastboot.common.entity.R;
import com.filldream.fastboot.common.util.entity.wxpay.WxC2BSTO;
import com.filldream.fastboot.common.util.entity.wxpay.WxRefundSTO;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.time.Instant;
import java.util.Map;

/**
 * @author RickSun && iFillDream
 * @version 1.0
 * @data 2020-05-15 14:20
 * @description 微信支付
 * 详见:https://pay.weixin.qq.com/wiki/doc/api/index.html
 */
@Slf4j
public class WxPayUtil {

    //微信支付SignKey
    private static final String signKey = "signKey";

    //统一下单
    private static final String unifiedorderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    //微信退款
    private static final String refundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";

    /**
     * @author RickSun
     * @Description 退款
     * @return 退款结果
     **/
    public static R<Map<String, String>> refund(WxRefundSTO wxRefundSTO){
        Map<String, String> sortedParams = wxRefundSTO.toMap();
        sortedParams.put("nonce_str",RandomUtil.randAlphaNumString(31).toUpperCase());
        sortedParams.put("refund_account","REFUND_SOURCE_RECHARGE_FUNDS");
        sortedParams = wxRefundSTO.sign(sortedParams,signKey);
        String reqXml = XmlUtil.map2Xml(sortedParams);
        log.info("--->申请退款:" + JsonUtil.toJson(sortedParams));
        String resXml  = PayUtil.postData(refundUrl,wxRefundSTO.getMch_id(), reqXml);
        log.info("--->申请退款返回:" + resXml);
        Map<String, String> map = XmlUtil.xmlToMap(resXml);
        if(map.containsKey("result_code") && map.get("result_code").equals("SUCCESS") ){
            return R.successd(map);
        }
        return R.diy(ErrorCode.WECHAT_PAY_ERR.reMsg(),map,map.containsKey("err_code_des") ? map.get("return_msg") + map.get("err_code_des") : map.get("return_msg"));
    }

    /**
     * @author RickSun
     * @Description 用户支付给商户
     **/
    public static Map<String, String> user2Company(WxC2BSTO wxPaySTO) {
        Map<String, String> sortedParams = wxPaySTO.toMap();
        sortedParams.put("nonce_str",RandomUtil.randAlphaNumString(31).toUpperCase());
        sortedParams.put("spbill_create_ip", RequestContext.getRequest().getRemoteAddr());
        sortedParams = wxPaySTO.sign(sortedParams,signKey);
        log.info("WxPay Sign:{}",sortedParams.get("sign"));
        Map<String, String> orderResult = toPay(sortedParams);
        //再次签名
        Map<String, String> map = wxPaySTO.reSign(orderResult,signKey);
        log.info("Pay Result Map:{},WxPay ReSign:{}",orderResult,map);
        return map;
    }

    /**
     * @author RickSun
     * @Description 统一下单
     **/
    public static Map<String,String> toPay(Map<String,String> sortedParams){
        String parseXml = XmlUtil.map2Xml(sortedParams);
        Map<String,String> resultInfo;
        try {
            String s = UrlUtil.doPost(unifiedorderUrl, parseXml);
            resultInfo = XmlUtil.xmlToMap(s);
            if("SUCCESS".equals(resultInfo.get("return_code")) && "SUCCESS".equals(resultInfo.get("result_code")) ){
                resultInfo.put("timeStamp", Instant.now().getEpochSecond()+"");
                return resultInfo;
            }else{
                throw new GlobalException(ErrorCode.WECHAT_PAY_ERR.reMsg(),JsonUtil.toJson(resultInfo),true);
            }
        } catch (IOException e) {
            throw new GlobalException(ErrorCode.WECHAT_PAY_ERR.reMsg("失败"),e,true);
        }
    }

}
